home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Scene Storm
/
Scene Storm - Volume 1.iso
/
coding
/
asm
/
games
/
shootemup
/
shootemup.s
< prev
Wrap
Text File
|
1980-01-03
|
37KB
|
1,548 lines
*****************************************************************************
* Shoot Em Up, By Phagex/LSD 1992/93. Source & GFX Copyright LSD 1993 *
*****************************************************************************
* Coded in Devpac 3.02, NOT PC RELATIVE! Disable cache and AGA if crashes *
* on A1200/A4000!! Sorry i aint fully checked it, but i did get it to run *
* okay on Pazzas A1200 once! *
*****************************************************************************
Opt c-
Section "LSD Game Code",Code_c
*****************************************************************************
AlienType = 3 ; GFX Type for alien, 2 to 6
Start Movem.l d0-d7/a0-a6,-(sp) ; Save Regs
Bsr KillSys ; Kill DOS System
Bsr PlayTheGame
Bsr ReturnSys ; Otherwise say goodbye
Movem.l (sp)+,d0-d7/a0-a6 ; and put 68000 regs
Moveq #0,d0 ; back to system values..
Rts
PlayTheGame Move.w #6,Lives ; Set 6 Lives
Move.l #0,Score ; And score to Nill
Move.w #0,DeadCount ; Reset Ship Explosion
Bsr DoubleBuffer ; Setup Piccy Addresses
Bsr SetTextBPLS ; Set CopperList BPLS
Bsr DoScore ; Show Score line
Lea Piccy1,a0 ; Clear Both Piccy buffers
Bsr CLS ;
Lea Piccy2,a0 ;
Bsr CLS ;
Move.l #CopperList1,$Dff080 ; Set Game Copper
Lea $Dff000,a6 ;
Move.w #$87c0,DMACon(a6) ; Set DMA
Bsr SetMouse ; Reset Mouse X&Y
Move.w #152,XPos ; Set ship start position
Move.w #250,YPos ; X&Y.
Bsr DoLives ; Show Player lives
Bsr ResetALL ; Reset all variables
*****************************************************************************
* Main Game Processing Loop starts here.. *
*****************************************************************************
Loop Bsr ClearBullets ; Clear the different
Bsr ClearAliens ; objects on screen
Bsr ClearShip ; individually...
Bsr ClearExplosions ;
***************************************************
Bsr MoveBullets ; Move and show Bullets
Bsr ShowBullets ; (Fire power)
Bsr Randomize ; Randomize Alien X Pos
Bsr NewAlien ; Start a new alien if poss,
Bsr MoveAliens ; Move 'em down screen
Bsr CheckBullets ; Check if they've been shot
Bsr ShowAliens ; Show if otherwise.
Bsr UpdateExplo ; Update the Explosion
Bsr ShowExplosions ; Animations & show them
Cmp.w #0,DeadCount ; If Dying, skip next few
Bne NoBlitShip ; routines
Bsr CheckAliens ; Check for a collision
Bsr TrackStick ; Get JoyStick status,
Bsr TrackMouse ; Get Mouse Position
Bsr MoveShip ; Move ship around screen.
Btst #0,Altern8 ; Double buffer ships X&Y
Bne SPos1 ; positions, for use with
Move.w XPos,FCXPos0 ; the clearing routine l8r.
Move.w YPos,FCYPos0 ;
Bra SPos2 ;
SPos1 Move.w XPos,FCXPos1 ;
Move.w YPos,FCYPos1 ;
;
SPos2 Bsr BlitShip ; Finally show the ship.
***************************************************
DoVBL Bsr VBL ; Syncro with Vertical
Movem.l d0-d7/a0-a6,-(sp) ; Blank.
Bsr DoubleBuffer ; Double Buffer Piccy
Movem.l (sp)+,d0-d7/a0-a6 ;
Bsr FrameCount ; Increase Timer
***************************************************
Cmp.w #-1,Lives ; If No lives left then
Beq Die ; GAME OVER!
Btst #2,$Dff016 ; Loop again if left mouse
Bne Loop ; button not pressed..
QuitTheGame Rts ; Exit MainLoop
NoBlitShip Sub.w #1,DeadCount ; Wait for the ships
Cmp.w #0,DeadCount ; explosion to finish its
Beq DoReset ; animation.
Bra DoVBL ;
DoReset Bsr ResetAll ; Lose a life and
Bra Loop ; return to Loop
ResetAll Lea BlackOut,a4 ; Fade the Screen palette
Bsr FadeOut ; to black.
Lea BullTable,a0 ; Clean out bullet table
Move.w #11,d7 ;
BTCLoop Move.l #-1,(a0)+ ;
Dbf d7,BTCLoop ;
Lea AlienTable,a0 ; Clean out old Aliens
Move.w #29,d7 ;
ATCLoop Move.l #-1,(a0)+ ;
Move.l #-1,(a0)+ ;
Dbf d7,ATCLoop ;
Lea ExploTable,a0 ; Clean out old Explosions
Move.w #29,d7 ;
ETCLoop Move.l #-1,(a0)+ ;
Move.w #-1,(a0)+ ;
Dbf d7,ETCLoop ;
Lea Piccy1,a0 ; Clear Picture buffers 1&2
Bsr CLS ;
Lea Piccy2,a0 ;
Bsr CLS ;
Bsr DoScore ; Show Updated Score line
Move.w #152,XPos ; Reset Ships start co-ords.
Move.w #250,YPos ;
Bsr DoGetReadyMSG ; Show GET READY! Text.
Move.w #$fff,CopperCols+6 ; Get Ready text = White
Move.w #140,d2 ; Do a quick pause
Bsr Pause ;
Lea PiccyCols0,a4 ; Fade out GET READY!
Bsr FadeOut ;
Lea Piccy1,a0 ; Clear Picture Buffers
Bsr CLS ;
Lea Piccy2,a0 ;
Bsr CLS ;
Rts ; Exit to Main Loop
Die Lea BlackOut,a4 ; Fade out palette to Black
Bsr FadeOut
Lea Piccy1,a0 ; Clear Picture buffers.
Bsr CLS ;
Lea Piccy2,a0 ;
Bsr CLS ;
Bsr DoScore ; Update Score.
Bsr DoGameOverMSG ; Show GAME OVER! Text
Lea PiccyCols1,a4 ; Fade in Text palette.
Bsr FadeOut ;
Move.w #250,d2 ; Pause for 5 secs.
Bsr Pause ;
Lea BlackOut,a4 ; Fade out Game Over.
Bsr FadeOut ;
Bra QuitTheGame ; Quit Loop
Pause Bsr VBL ; Quick Loop that Pauses
Move.w #$1000,d1 ; until d2 = 0 or Left Mouse
PauseLoop Dbf d1,PauseLoop ; or JoyStick buttons are
Btst #6,$Bfe001 ; Pressed.
Beq QuitPause ;
Btst #7,$Bfe001 ;
Beq QuitPause ;
Dbf d2,Pause ;
QuitPause Rts ;
FadeOut Move.w #16,d7 ; Fade routine to Fade the
FadeOutLoop Bsr VBL ; Palette in the copper list
Move.w #$3000,d0 ; to whatever you want.
FadeWait Dbf d0,FadeWait ;
Move.l d7,-(sp) ;
Move.l a4,a1 ;
Bsr FadeX ;
Move.l (sp)+,d7 ;
Dbf d7,FadeOutLoop ;
Rts ;
FadeX Lea CopperCOLS+2,a0 ; Get CopperList Palette
Move.w #15,d7 ; Set a 16 Colour Loop
FadeLoop Moveq #0,d4 ;
Move.w (a0),d0 ; Get Copper Colour
Move.w (a1)+,d1 ; Get Colour to Fade to.
;
Move.w #$001,d5 ; Get Blue Increment
Move.w #$00f,d6 ; Get Blue Colour
Bsr DoFadeX ; Fade Blue
Move.w #$010,d5 ; Get Green Inc
Move.w #$0f0,d6 ;
Bsr DoFadeX ; Fade Green
Move.w #$100,d5 ; Get Red
Move.w #$f00,d6 ;
Bsr DoFadeX ; Fade Red.
;
Move.w d4,(a0) ; Final result into Copper.
Addq #4,a0 ; Next Colour Please!
Dbf d7,FadeLoop ;
Rts ;
;
DoFadeX Move.w d0,d2 ; Fade Routine that takes
Move.w d1,d3 ; either Red, Green or Blue
And.w d6,d2 ; And Increases or Decreases
And.w d6,d3 ; towards the value of the
Cmp.w d2,d3 ; chosen colour.
Blt FadeXDown ;
Bgt FadeXUp ;
Bra NoFadeX ;
;
FadeXDown Sub.w d5,d2 ; Decrease colour
Bra NoFadeX ;
FadeXUp Add.w d5,d2 ; Increase colour
Bra NoFadeX ;
;
NoFadeX Or.w d2,d4 ; Put new colour back.
Rts ;
*****************************************************************************
CLS Move.w #(10*4*270)-1,d0; Simple Clear screen Loop
CLoop1 Move.l #0,(a0)+ ;
Dbf d0,CLoop1 ;
Rts
*****************************************************************************
T = (40*3*20) ; BitPlane Offset (Hides aliens)
DoubleBuffer Bchg #0,Altern8 ; Alternate frame swap for
Btst #0,Altern8 ; double buffer..
Bne DBuffer ;
Move.l #Piccy1,Screen ; Set Blits to Piccy1 and
Move.l #Piccy2+T,d0 ; Copperlist to Piccy2
Lea Bpl0,a0 ;
Bra SetBPLS ; Jump to Bitplane Setter
DBuffer Move.l #Piccy2,Screen ; Set Blits to Piccy2 and
Move.l #Piccy1+T,d0 ; Copperlist to Piccy1
Lea Bpl0,a0 ;
SetBPLS Move.w #3,d7 ;
SetBPLoop Move.l d0,d1 ;
Move.w d1,6(a0) ;
Swap d1 ; Set the Bitplanes in the
Move.w d1,2(a0) ; Copperlist to the new
Add.l #$28,d0 ; Piccy...
Add.l #$8,a0 ;
Dbf d7,SetBPLoop ;
Rts
*****************************************************************************
SetTextBPLS Lea TextBpls,a0 ; Set the text BPLS in the
Move.l #TextPiccy,d0 ; CopperList
Move.w d0,6(a0) ;
Swap d0 ;
Move.w d0,2(a0) ;
Rts ;
*****************************************************************************
VBL Move.l $Dff004,d0 ; Fetch VBL Position
And.l #$1ff00,d0 ;
Cmp.l #$02000,d0 ; Wait for Position $20
Bne VBL ;
Rts ; Return when reached..
*****************************************************************************
FrameCount Add.w #1,MSecs ; Add 1 to Frame 50ths,
Cmp.w #50,MSecs ;
Bne NotSec ; When 50, clear and add 1
Move.w #0,MSecs ; to Seconds
Add.w #1,Secs ;
Cmp.w #60,Secs ;
Bne NotSec ; When 60, clear and add 1
Move.w #0,Secs ; to Minutes
Add.w #1,Mins ;
Cmp.w #60,Mins ;
Bne NotSec ; When 60, clear and add 1
Move.w #0,Mins ; to Hours...
Add.w #1,Hours ;
NotSec Rts
*****************************************************************************
MoveShip Move.b MoveFlag,d0 ; Get Movement Flags
Move.w Speed,d1 ; Get Ship Speed
Btst #0,d0 ; Test for Move Right
Beq NoR ; Jump to next test if no
Add.w d1,XPos ; Add Speed to right..
NoR Btst #1,d0 ; Test for Move Left
Beq NoL ;
Sub.w d1,XPos ;
NoL Btst #2,d0 ; Test for Move Down
Beq NoD ;
Add.w d1,YPos ;
NoD Btst #3,d0 ; Test for Move Up
Beq NoU ;
Sub.w d1,YPos ;
NoU Tst.w XPos ; Test for X Position 0
Bpl NX1 ; if less than 0 (off Screen)
Move.w #0,XPos ; then put back to 0
NX1 Tst.w YPos ; Test for Y Position 0
Bpl NY1 ; if less than 0 (off Screen)
Move.w #0,YPos ; put back to 0
NY1 Cmp.w #299,XPos ; Test X Pos 299
Ble NX2 ; if greater, then off screen
Move.w #299,XPos ; put down to 299
NX2 Cmp.w #240,YPos ; Test Y Pos 240
Ble NY2 ; if greater, then off screen
Move.w #240,YPos ; put down yo 240
NY2 Btst #4,d0 ; Fire button pressed??
Beq NoShoot ; no, then Exit routine
Add.w #1,BulletCount ; Count 5 frames before
Cmp.w #5,BulletCount ; releasing another bullet
Bne NoShoot ; (screen becomes cluttered
Move.w #0,BulletCount ; otherwise)
Bsr SetBullet ; Set a bullet if 5th Frame
NoShoot Rts
*****************************************************************************
BlitShip Add.w #1,Frame ; Next ship frame
And.w #$f,Frame ; No more than 16 frames
Lea AlienGFX1,a0 ; Point to the Raw GFX Data
Lea AlienMask1,a1 ; Point to the GFX Mask
Move.w #0,d0 ; The Sprite Row number
Move.w Frame,d1 ; The Frame number
Move.w XPos,d2 ; X Co-ord
Move.w YPos,d3 ; Y Co-ord
Move.w #16,d4 ; Height in Pixels
Bsr Blitter
Rts
*****************************************************************************
ClearShip Btst #0,Altern8 ;
Bne CLPos1 ;
Move.w FCXPos0,d0 ;
Move.w FCYPos0,d1 ; This routine takes the last
Bra CLPos2 ; double buffered position
CLPos1 Move.w FCXPos1,d0 ; and clears the space the
Move.w FCYPos1,d1 ; ship takes up..
CLPos2 Move.w #16,d2 ;
Bsr BlitClear ;
Rts ;
*****************************************************************************
SetBullet Lea BullTable,a0 ;
NextBullet Move.w 0(a0),d0 ;
Move.w 2(a0),d1 ;
Cmp.w #-1,d0 ; Find an unused bullet in
Beq FreeBullet ; the bullet table and set
Lea 4(a0),a0 ; its new position...
Cmp.l #BullEnd,a0 ;
Beq NoMoreBullets ;
Bra NextBullet ;
;
FreeBullet Move.w XPos,0(a0) ;
Move.w YPos,2(a0) ;
NoMoreBullets Rts
*****************************************************************************
MoveBullets Lea BullTable,a0 ;
Move.w BullSpeed,d6 ;
Move.w #7,d7 ; Move all the Active bullets
BullMLoop Sub.w d6,2(a0) ; up the screen..
Cmp.w #2,2(a0) ;
Ble KillBullet ; Kill the bullet if it
NextMBull Add.l #4,a0 ; reaches the top of the
Dbf d7,BullMLoop ; screen...
Rts ;
KillBullet Move.l #-1,(a0) ;
Bra NextMBull ;
*****************************************************************************
ShowBullets Lea BullTable,a5 ;
Btst #0,Altern8 ;
Bne Save1 ; Now read the bullet table
Lea FCBullets0,a4 ; and blit all the active
Bra Save2 ; bullets...
Save1 Lea FCBullets1,a4 ;
Save2 Move.w #7,d7 ;
DoSBulls Move.w (a5)+,d2 ;
Move.w (a5)+,d3 ;
;
Move.w d2,(a4)+ ;
Move.w d3,(a4)+ ;
;
Cmpi.w #-1,d2 ;
Beq NoShowBullet ;
;
Lea AlienGFX1,a0 ;
Lea AlienMask1,a1 ;
Move.w #0,d0 ;
Move.w #19,d1 ;
Move.w #8,d4 ;
Bsr Blitter ;
;
NoShowBullet Dbf d7,DoSBulls ;
Rts
*****************************************************************************
ClearBullets Btst #0,Altern8 ;
Bne Load1 ;
Lea FCBullets0,a5 ; Now read the Double
Bra Load2 ; buffered list of bullets
Load1 Lea FcBullets1,a5 ; and clear active ones..
Load2 Move.w #7,d7 ;
DoCBulls Move.w (a5)+,d0 ;
Move.w (a5)+,d1 ;
;
Cmpi.w #-1,d0 ;
Beq NoClearBullet ;
;
Move.w #8,d2 ;
Bsr BlitClear ;
;
NoClearBullet Dbf d7,DoCBulls ;
Rts
*****************************************************************************
Blitter Lea $Dff000,a6 ; Base of the Custom Regs
Move.l #(40*4*16),d5
And.l #63,d0
Muls d0,d5 ; Find Address of GFX Row
Move.w d1,d0
Asl.w #1,d0 ; Find Address of Frame
Add.l d0,a0 ;
Add.l d0,a1 ; Add Frame & Row to both
Add.l d5,a0 ; GFX and Mask Pointers
Add.l d5,a1 ;
Move.l Screen,a2 ; Point to Screen Base
Move.w d3,d0 ; Get Y Co-ord
Move.l #$28*4,d1 ;
Muls d0,d1 ; Find Y Co-ord pos and Add
Add.l d1,a2 ; to the Screen Pointer
Move.w d2,d0 ; Get X Co-ord
Moveq #0,d1 ;
Move.w d0,d1 ;
Asr.w #3,d1 ; Divide by 8 pixels,
Bclr #0,d1 ; Make sure even number
Add.l d1,a2 ; and to Screen Pointer
And.w #$f,d0 ; Get Blitter Offset
Bsr BWait ; Wait For Blitter
Move.l a1,BltApth(a6) ; Mask Pointer
Move.l a0,BltBpth(a6) ; GFX Pointer
Move.l a2,BltCpth(a6) ; Screen Pointer
Move.l a2,BltDpth(a6) ; Screen Pointer
Move.w #36,BltAMod(a6) ; Set all Modulos to 36
Move.w #36,BltBMod(a6) ;
Move.w #36,BltCMod(a6) ;
Move.w #36,BltDMod(a6) ;
Move.l #$ffff0000,BltAFWM(a6) ; Set Mask
Lea BConShift,a0 ; Now find our Control code
Asl.w #2,d0 ; for the relative Offset
Move.l (a0,d0.l),d1 ;
Move.l d1,BltCon0(a6) ;
Move.w #4,d1 ; Amount of Bitplanes to blit
Muls d1,d4 ; Multiply Height by 4,
Asl.w #6,d4 ; Move Left 6 bits for reg
Or.w #2,d4 ; Add X size (2 words)
Move.w d4,BltSize(a6) ; Start Blitter!!
Rts
*****************************************************************************
BlitClear Lea $Dff000,a6
Move.l Screen,a2 ;
Move.l #$28*4,d4 ; Calc Y Screen Position
Muls d1,d4 ;
Add.l d4,a2 ;
Moveq #0,d1 ;
Move.w d0,d1 ;
Asr.w #3,d1 ; Calc X Screen Position
Bclr #0,d1 ; (No need to Offset)
Add.l d1,a2 ;
Bsr BWait ; Wait for Blitter
Move.l a2,BltDpth(a6) ; Set Desination Regs only
Move.w #36,BltDMod(a6) ;
Move.l #$ffffffff,BltAFWM(a6) ; Full Mask
Move.l #$01000000,BltCon0(a6) ; Blit No-Operation
Move.w #4,d1 ; Amount of Bitplanes to blit
Muls d1,d2 ; Multiply Height by 4,
Asl.w #6,d2 ; Move Left 6 bits for reg
Or.w #2,d2 ; Add X size (2 words)
Move.w d2,BltSize(a6) ; Start Blitter!!
Rts
Randomize Movem.l d0-d1/a0,-(sp) ;
Move.l RandPos,a0 ;
Move.l (a0)+,d0 ;
Or.l Screen,d0 ; Calculate a nice random
Move.l XPos,d1 ; number..
Eor.l d1,d0 ;
Add.l (a0)+,d0 ; Using X & Y Pos, the
Add.l Msecs,d0 ;
Move.l $Dff004,d1 ;
Eor.l d1,d0
Move.l a0,RandPos ; Kickstart ROM Data and
Add.l d1,d0 ; the Screen Pointer.
Move.l d0,RandNo ;
Movem.l (sp)+,d0-d1/a0 ;
Rts
*****************************************************************************
NewAlien Add.w #1,AlienCount ; Count 10 Frames before
Cmp.w #10,AlienCount ; releasing another alien
Beq ReleaseAlien ; onto the screen.
Rts
ReleaseAlien Move.w #0,AlienCount
APatt0 Move.l RandNo,d0 ; Use the Random number for
And.w #$1ff,d0 ; Alien X Pos, and Speed.
Cmpi.w #299,d0 ; Alien off the screen?
Blt NoSubit0 ;
Sub.w #299,d0 ; Pull him back on then.
NoSubit0 Move.w d0,AXPos
Move.l RandNo,d0 ;
Swap d0 ;
Asr.w #8,d0 ; Find a Speed for this
And.w #7,d0 ; New Alien chum..
Cmpi.b #0,d0 ;
Beq NotZero0 ;
Move.b d0,d5 ;
DoSetA0 Move.w #0,d6
Bsr SetAlien
Rts
NotZero0 Move.w #1,d5 ; But Not a 0 Speed
Bra DoSetA0
*****************************************************************************
SetAlien Lea AlienTable,a0 ; Now find a free space in
ALLoop Move.w 0(a0),d0 ; the Alien movement chart
Cmp.w #-1,d0 ; for our new friend..
Beq FreeAlien ; Found a Free Space??
Lea 8(a0),a0 ; Check Next Space if not..
Cmp.l #AlienEnd,a0 ; But Find out if we've
Beq ALTabEnd ; run out of chart..
Bra ALLoop ;
FreeAlien Move.b d5,0(a0) ; Put our new Alien
Asl.w #1,d6
Bset #0,d6
Move.b d6,1(a0) ; characteristics into the
Move.w AXPos,2(a0) ; free chart Space..
Move.w #0,4(a0) ;
Move.w #0,6(a0) ;
ALTabEnd Rts
*****************************************************************************
MoveAliens Lea AlienTable,a0 ;
Move.w #19,d7 ;
MVALoop Move.w 0(a0),d0 ;
Cmp.w #-1,d0 ; Test to see if the Alien
Bne MoveAlien ; is alive and kicking,
DoMVALoop Lea 8(a0),a0 ; if not, try the next one..
Dbf d7,MVALoop ;
Rts
MoveAlien Asr.w #1,d0
And.w #$7f,d0
Cmpi.b #00,d0
Beq MVAPatt0
Bra DoMVALoop
MVAPatt0 Moveq #0,d6 ;
Move.b 0(a0),d6 ; Get Alien Speed
Add.w d6,4(a0) ; Add to its Y Position
Add.w #1,6(a0) ; Add 1 to the Alien frame
And.w #$f,6(a0) ; No more than 16 frames..
Cmp.w #260,4(a0) ; Is Alien off screen yet?
Bgt ALOffScreen ; Yes, then free his Chart
Bra DoMVALoop ; space, otherwise Next Alien
ALOffScreen Move.w #-1,0(a0) ;
Move.w #-1,2(a0) ; Clear this Aliens
Move.w #-1,4(a0) ; characteristics out of
Move.w #-1,6(a0) ; the chart Space...
Bra DoMVALoop ; Next Alien Please...
*****************************************************************************
ShowAliens Lea AlienTable,a5 ; Now Show the Aliens in
Btst #0,Altern8 ; the chart Spaces...
Bne SaveA1 ;
Lea FCAliens0,a4 ; Which Alien list do we
Bra SaveA2 ; want first...
SaveA1 Lea FCAliens1,a4 ; (Double Buffered)
SaveA2 Move.w #19,d7 ;
DoSAliens Move.w (a5)+,d4 ; Get Alien Speed,
Move.w (a5)+,d2 ; Alien X Position,
Move.w (a5)+,d3 ; Y Position and
Move.w (a5)+,d1 ; Frame
Move.w d4,(a4)+ ; Save Speed, X & Y and
Move.w d2,(a4)+ ; Frame in our Double Buffer
Move.w d3,(a4)+ ; List..
Move.w d1,(a4)+ ;
Cmp.w #-1,d4 ; Is Alien Active?
Beq NoShowAlien ; No, then Don't Blit then..
Lea AlienGFX1,a0
Lea AlienMask1,a1
Move.w #AlienType,d0 ; GFX Row
Move.w #16,d4 ; 16 Pixels for Alien
Bsr Blitter
NoShowAlien Dbf d7,DoSAliens
Rts
*****************************************************************************
ClearAliens Btst #0,Altern8 ; As Above Routine, but
Bne LoadA1 ; clear screen instead of
Lea FCAliens0,a4 ; Blit Alien...
Bra LoadA2
LoadA1 Lea FCAliens1,a4
LoadA2 Move.w #19,d7
DoCAliens Move.w (a4)+,d4
Move.w (a4)+,d0
Move.w (a4)+,d1
Move.w (a4)+,d3
Cmp.w #-1,d4
Beq NoClearAlien
Move.w #16,d2
Bsr BlitClear
NoClearAlien Dbf d7,DoCAliens
Rts
*****************************************************************************
CheckBullets Lea BullTable,a0 ; Now to check all the
Move.w #7,d7 ; bullets to see if they
CBullLoop0 Move.w 0(a0),d0 ; manage to hit any Aliens..
Move.w 2(a0),d1 ; Get Bullet X & Y..
Cmp.w #-1,d0 ; If bullet inactive then
Beq NoBullCheck ; try next one..
Sub.w #7,d0 ;
Lea AlienTable,a1 ;
Move.w #19,d6 ;
CBullLoop1 Move.w 0(a1),d3
Cmp.w #-1,d3
Beq OutOfRange
Move.w 2(a1),d3 ; Get Alien X & Y Positions.
Move.w 4(a1),d4 ;
Cmp.w d0,d3 ; Is Bullet Outside Alien X
Blt OutOfRange ; Position??
Sub.w #16,d3 ; Is Bullet Outside Still
Cmp.w d0,d3 ; Outside 16 pixel Offset??
Bgt OutOfRange ;
Cmp.w d1,d4 ; Now do the same with the
Blt OutOfRange ; Y Position..
Sub.w #16,d4 ; And Again..
Cmp.w d1,d4 ;
Bgt OutOfRange ;
Collide Move.b 0(a1),d6 ; Get Speed of Alien..
Move.w 2(a1),d3 ; Get Alien X & Y Positions.
Move.w 4(a1),d4 ;
Move.w #-1,0(a1) ; Now Clear Aliens
Move.w #-1,2(a1) ; Characteristics. He's Dead!
Move.w #-1,4(a1) ;
Move.w #-1,6(a1) ;
And.b #$f,d6 ; Get the Aliens Speed and
Add.l d6,Score ; add to the score..
Movem.l d0-d7/a0-a6,-(sp)
Bsr DoScore
Movem.l (sp)+,d0-d7/a0-a6
Move.l #-1,(a0) ; Kill the Bullet..
Move.w d3,d5
Move.w d4,d6
Bsr SetExplosion
Move.w d3,d0
Move.w d4,d1
Move.w #16,d2
Bsr BlitClear
Bra NoBullCheck
OutOfRange Lea 8(a1),a1 ; Now do the Next Alien
Dbf d6,CBullLoop1 ;
NoBullCheck Add.l #4,a0
Dbf d7,CBullLoop0 ; And now the next bullet...
Rts
*****************************************************************************
CheckAliens Move.w XPos,d0 ; Get Ship X & Y Positions..
Move.w YPos,d1 ;
Move.w d0,d5 ; Remember the X & Y for the
Move.w d1,d6 ; Explosion if necessary..
Sub.w #7,d0 ;
Sub.w #10,d1
Lea AlienTable,a1 ;
Move.w #19,d7 ;
CAlienLoop Move.w 0(a1),d3
Cmp.w #-1,d3
Beq ALOutOfRange
Move.w 2(a1),d3 ; Get Alien X & Y Positions.
Move.w 4(a1),d4 ;
Cmp.w d0,d3 ; Is Ship Outside Alien X
Blt ALOutOfRange ; Position??
Sub.w #16,d3 ; Is Ship Outside Still
Cmp.w d0,d3 ; Outside 16 pixel Offset??
Bgt ALOutOfRange ;
Cmp.w d1,d4 ; Now do the same with the
Blt ALOutOfRange ; Y Position..
Sub.w #16,d4 ; And Again..
Cmp.w d1,d4 ;
Bgt ALOutOfRange ;
CollideAlien Add.l #50,Score ; Bonus for dying!!
Movem.l d0-d7/a0-a6,-(sp) ;
Bsr SubLives ; Now Display Lives amount
Movem.l (sp)+,d0-d7/a0-a6 ;
Move.w #32,DeadCount ; Start Death Sequence
Bsr SetExplosion
Bra NoAlienCheck
ALOutOfRange Lea 8(a1),a1 ; Now do the Next Alien
Dbf d7,CAlienLoop ;
NoAlienCheck Rts
*****************************************************************************
SetExplosion Lea ExploTable,a3 ;
NextExplosion Cmp.w #-1,0(a3) ; Find an unused Explosion in
Beq FreeExplosion ; the table and set its new
Lea 6(a3),a3 ; position...
Cmp.l #ExploEnd,a3 ;
Beq NoMoreExplo ;
Bra NextExplosion ;
;
FreeExplosion Move.w d5,0(a3) ;
Move.w d6,2(a3) ;
Move.w #0,4(a3) ;
NoMoreExplo Rts
*****************************************************************************
UpdateExplo Lea ExploTable,a0 ;
Move.w #19,d7 ;
ExploULoop Cmp.w #-1,0(a0) ; Is Explosion Active?
Beq NextUExplosion ; do next one if not..
Add.w #1,4(a0) ; Add 1 to the Explosion
Cmp.w #18,4(a0) ; Frame, if Last frame then
Beq KillExplosion ; kill the Explosion....
NextUExplosion Add.l #6,a0 ; Do next explosion now
Dbf d7,ExploULoop ;
Rts ;
KillExplosion Move.l #-1,0(a0) ; Kill Explosion Positions
Move.w #-1,4(a0) ; and free its table space.
Bra NextUExplosion ; Next Explosion please..
*****************************************************************************
ShowExplosions Lea ExploTable,a5 ; Now Show the Explosions in
Btst #0,Altern8 ; the chart Spaces...
Bne SaveEX1 ;
Lea FCExplo0,a4 ; Which Explo list do we
Bra SaveEX2 ; want first...
SaveEX1 Lea FCExplo1,a4 ; (Double Buffered)
SaveEX2 Move.w #19,d7 ;
DoSExplo Move.w (a5)+,d2 ; Explosion X Position and
Move.w (a5)+,d3 ; Y Position...
Move.w (a5)+,d1 ;
Move.w d2,(a4)+ ; Store Frame in our Double
Move.w d3,(a4)+ ; Buffer List..
;
Cmpi.w #-1,d2 ;
Beq NoShowExplo ;
;
Lea AlienGFX1,a0 ;
Lea AlienMask1,a1 ;
Move.w #1,d0 ;
Move.w #16,d4 ;
Bsr Blitter ;
;
NoShowExplo Dbf d7,DoSExplo ;
Rts
*****************************************************************************
ClearExplosions Btst #0,Altern8 ; As Above Routine, but
Bne LoadEX1 ; clear screen instead of
Lea FCExplo0,a4 ; Blit Alien...
Bra LoadEX2
LoadEX1 Lea FCExplo1,a4
LoadEX2 Move.w #19,d7
DoCExplo Move.w (a4)+,d0
Move.w (a4)+,d1
Cmpi.w #-1,d0 ;
Beq NoClearExplo ;
;
Move.w #16,d2 ;
Bsr BlitClear ;
;
NoClearExplo Dbf d7,DoCExplo ;
Rts
*****************************************************************************
DoText Movem.l d0-d7/a0-a6,-(sp)
Move.l TextPT,a0
Moveq #0,d6
Move.w TextMod,d6
Move.w #0,CXPos
NextChar Moveq #0,d0
Move.b (a0)+,d0
Cmp.b #0,d0
Beq TextEnd
Sub.b #32,d0
Asl.w #3,d0
CharShow Lea FontGFX,a4
Add.l d0,a4
Move.l TextSC,a5
Moveq #0,d0
Move.w CXPos,d0
Add.l d0,a5
Move.w #7,d7
CharCopy Move.b (a4)+,(a5)
Add.l d6,a5
Dbf d7,CharCopy
Space Add.w #1,CXPos
Bra NextChar
TextEnd Movem.l (sp)+,d0-d7/a0-a6
Rts
DoScore Move.l Score,d6
Lea ScoreNo,a0
DoScoreC Move.l #10000,d1
Bsr DoDivs
DoThousands Move.l #1000,d1
Bsr DoDivs
DoHundreds Move.l #100,d1
Bsr DoDivs
DoTens Move.l #10,d1
Bsr DoDivs
DoUnits Move.l #1,d1
Bsr DoDivs
Move.l #TextPiccy,TextSC
Move.l #ScoreText,TextPT
Move.w #40,TextMod
Bsr DoText
Rts
DoGetReadyMSG Move.l #GetReadyText,TextPT
Bra DoMSG
DoGameOverMSG Move.l #GameOverText,TextPT
DoMSG Move.l #Piccy1+(40*4*120),TextSC
Move.w #160,TextMod
Move.w #0,CXPos
Bsr DoText
Move.l #Piccy2+(40*4*120),TextSC
Move.w #0,CXPos
Bsr DoText
Rts
DoDivs Divs d1,d6
Move.w d6,d5
And.w #$f,d5
Add.w #48,d5
Move.b d5,(a0)+
Move.w #0,d6
Swap d6
Rts
SubLives Sub.w #1,Lives
Cmp.w #-1,Lives
Bne DoLives
Rts
DoLives Move.w Lives,d6
Lea LivesNo,a0
Bra DoTens
*****************************************************************************
BWait Btst #14,$Dff002 ; Test Blitter status bit
Bne BWait ; Not ready? Try again..
Rts
*****************************************************************************
KillSys Bsr SysWait ; Wait for System to Relax
Move.l $4,a6 ; Find EXEC Base
Lea GFXLibName,a1 ; Point to Library Name
Moveq #0,d0 ; Open GFX Library, to find
Jsr -552(a6) ; Old Copperlist
Lea OldCopper,a5 ;
Move.l $26(a0),(a5) ; Save old CopperList
Lea $Dff000,a6 ; Base of Custom Registers
Move.w IntEnaR(a6),d0 ; Find Old Interupts
Move.w DMAConR(a6),d1 ; And Old DMA Control
Or.w #$8000,d0 ;
And.w #$03ff,d1 ; Process Values for Exit
Or.w #$8000,d1 ;
Move.w #$7fff,IntEna(a6) ; Kill Ints
Move.w #$7fff,DMACon(a6) ; Kill DMA
Move.w d0,$4(a5) ; Remember Ints & DMA
Move.w d1,$6(a5) ;
Bset #1,$Bfe001 ; Switch off Sound Filter
Rts
*****************************************************************************
SysWait Move.w #15,d7 ; Pause a brief while to
SWLoop1 Move.w #$1000,d0 ; allow Devpac to settle
SWLoop2 Move.w d7,$Dff180 ; down, because the Keyboard
Move.w d7,$Dff182 ; routine gets upset if you
Move.w d7,$Dff184 ; kill the system before
Move.w d7,$Dff186 ; you release the keys..
Dbf d0,SWLoop2 ; (Colour change not
Dbf d7,SWLoop1 ; essential, but pretty..)
Rts
*****************************************************************************
ReturnSys Lea $Dff000,a6
Move.w OldIntEna,IntEna(a6) ; Replace System Ints,
Move.w OldDMACon,DMACon(a6) ; DMA Control
Move.l OldCopper,Cop1lc(a6) ; And Old Copperlist
Rts
*****************************************************************************
TrackMouse Lea $Dff000,a6
Move.w Joy0Dat(a6),d0 ; Register for Mouse port
Move.b OldX,d1 ;
Move.b d0,OldX ;
Sub.b d0,d1 ; Calc X Position of Mouse
Ext.w d1 ;
Sub.w d1,XPos ;
Lsr.w #8,d0 ; Get Y Pos Data
Move.b OldY,d1 ;
Move.b d0,OldY ;
Sub.b d0,d1 ; Calc Y Position of Mouse
Ext.w d1 ;
Sub.w d1,YPos ;
Move.w XPos,d0 ; Store X and Y Positions
Move.w YPos,d1 ;
Btst #6,$Bfe001
Bne NoLMB
Lea MoveFlag,a5 ; Set flags to indicate
Move.w #0,(a5) ; Fire button pressed.
Bset #4,(a5) ;
Bset #5,(a5) ;
NoLMB Rts
*****************************************************************************
SetMouse Lea $Dff000,a6 ;
Move.w Joy0Dat(a6),d0 ; Set the Mouse Position
Move.b d0,OldX ;
Lsr.w #8,d0 ;
Move.b d0,OldY ;
Rts
*****************************************************************************
TrackStick Lea MoveFlag,a5 ; Flags for Ship Movement
Lea $Dff000,a6
TestJoy And.w #%11000000,(a5)
Move.w Joy1Dat(a6),d0 ; The Joystick Port
Btst #1,d0
Beq JoyLeft
GoRight Bset #0,(a5)
Bset #5,(a5)
JoyLeft Btst #9,d0
Beq JoyDown
GoLeft Bset #1,(a5)
Bset #5,(a5)
JoyDown Move.w d0,d1
Lsr.w #1,d1
Eor.w d0,d1
Btst #0,d1
Beq JoyUp
GoDown Bset #2,(a5)
Bset #5,(a5)
JoyUp Btst #$8,d1
Beq JoyFire
GoUp Bset #3,(a5)
Bset #5,(a5)
JoyFire Btst #7,$Bfe001
Bne NoJoyFire
GoFire Bset #4,(a5)
Bset #5,(a5)
NoJoyFire Rts
*****************************************************************************
ScoreText Dc.b " Score "
ScoreNo Dc.b "0000000 Lives "
LivesNo Dc.b "00 Hi "
HiScoreNo Dc.b "0000000",0
Even
BlankText Dc.b " "
GetReadyText Dc.b " GET READY.. ",0
GameOverText Dc.b " GAME OVER.. ",0
Even
*****************************************************************************
* Variables *
*****************************************************************************
GFXLibName Dc.b "graphics.library",0,0,0,0
OldCopper Dc.l 0 ;
OldIntEna Dc.w 0 ; System Variables.
OldDmaCon Dc.w 0 ;
OldX Dc.b 0 ; Mouse Variables.
OldY Dc.b 0 ;
XPos Dc.w 0 ; Ship X & Y Co-ords.
YPos Dc.w 0 ;
AXPos Dc.w 0 ; Alien X & Y Co-ords.
AYPos Dc.w 0 ;
FCXPos0 Dc.w 0 ; Double Buffer X & Y 0.
FCYPos0 Dc.w 0 ;
FCXPos1 Dc.w 0 ; Double Buffer X & Y 1.
FCYPos1 Dc.w 0 ;
CXPos Dc.w 0 ; Font Print X & Y Co-ords.
CYPos Dc.w 0 ;
Frame Dc.w 0 ; Ship Frame No.
AFrame Dc.w 0 ; Alien Frame No.
MoveFlag Dc.w 0 ; Ships Movement Flags.
Speed Dc.w 4 ; Ships Speed.
BullSpeed Dc.w 8 ; Bullets Speed.
BulletCount Dc.w 0 ; Bullet Frame Counter.
Screen Dc.l Piccy1 ; Screen Address pointer.
Altern8 Dc.w 0 ; Double Buffer Alternate.
AlienCount Dc.w 0 ; Alien Release Counter
PattFrameCount Dc.w 0 ; Alien Frame Counter.
MSecs Dc.w 0 ; Clock 50ths,
Secs Dc.w 0 ; Seconds,
Mins Dc.w 0 ; Minutes,
Hours Dc.w 0 ; Hours.
RandPos Dc.l $f80000 ; Pointer to the ROM.
RandNo Dc.l 0 ; Random Generated Number.
Score Dc.l 0 ; Players Score.
Lives Dc.w 5 ; Ships Lives.
TextSC Dc.l 0 ; Text Screen Pointer.
TextPT Dc.l 0 ; Text Pointer.
TextMod Dc.w 0 ; Text Modulo Width.
DeadCount Dc.w 0
LevelPoint Dc.l Level1
LevCount Dc.w 0
*****************************************************************************
* Tables *
*****************************************************************************
BullTable ; Bullets lie here..
Rept 8
Dc.w -1,-1
EndR
BullEnd Dc.w $0,0
FCBullets0 ; Bullets Double Buffer 0.
Rept 8
Dc.w -1,-1
EndR
FCBullets1 ; Bullets Double Buffer 1.
Rept 8
Dc.w -1,-1
EndR
AlienTable ; Aliens lie in here...
Rept 20
Dc.w -1,-1,-1,-1
EndR
AlienEnd Dc.w $0,0
FCAliens0 ; Aliens Double Buffer 0.
Rept 20
Dc.w 0,0,0,0
EndR
FCAliens1 ; Aliens Double Buffer 1.
Rept 20
Dc.w 0,0,0,0
EndR
ExploTable
Rept 20
Dc.w -1,-1,-1
EndR
ExploEnd Dc.w 0,0
FCExplo0 ; Explo Double Buffer 0.
Rept 20
Dc.w 0,0,0,0
EndR
FCExplo1 ; Explo Double Buffer 1.
Rept 20
Dc.w 0,0,0,0
EndR
*****************************************************************************
* Alien Level Data *
*****************************************************************************
; Data :- No. of Patts in Set, Patt, Aline GFX, Score Each, $fff=End Marker
; Then Bonus for all killed
Level1 Dc.w 1,0,4,100,$fff
Dc.w -1,-1
*****************************************************************************
* Blitter Shift Data *
*****************************************************************************
BConShift Dc.l $0fca0000 ; This is for the Blitter
Dc.l $1fca1000 ; Control registers, to
Dc.l $2fca2000 ; save extra hassle they're
Dc.l $3fca3000 ; in this easy to look up
Dc.l $4fca4000 ; chart..
Dc.l $5fca5000 ;
Dc.l $6fca6000 ;
Dc.l $7fca7000
Dc.l $8fca8000
Dc.l $9fca9000
Dc.l $afcaa000
Dc.l $bfcab000
Dc.l $cfcac000
Dc.l $dfcad000
Dc.l $efcae000
Dc.l $ffcaf000
*****************************************************************************
* Macros *
*****************************************************************************
Cmv Macro ; CopperList Move Instruction
Dc.w \2,\1
EndM
Cwt Macro ; CopperList Wait Instruction
Dc.w (\1*$100)+$01,$fffe
EndM
Pal Macro ; CopperList Pal Wait
Dc.w $ffe1,$fffe
EndM
EndCop Macro ; CopperList End
Dc.w $ffff,$fffe
EndM
*****************************************************************************
* CopperList *
*****************************************************************************
CopperList1 Cwt $14 ; Wait for Off screen line
Cmv $0200,BplCon0 ; No Bitplanes - Clear
Cmv $0000,BplCon1 ; No Hardware Scroll Offset
Cmv $000a,BplCon2 ; Normal Bitplane Priority
Cmv $0032,DdfStrt ; Data Fetch Start
Cmv $00d0,DdfStop ; Data Fetch Stop
Cmv $163c,DiwStrt ; Window Start
Cmv $36c1,DiwStop ; Windto Stop
Cwt $15 ; Wait for Line $15
Cmv $0000,Color16 ;
Cmv $0000,Color17 ;
Cmv $0000,Color18 ;
Cmv $0000,Color19 ;
Cmv $0000,Color20 ;
Cmv $0000,Color21 ; Unused Colours
Cmv $0000,Color22 ;
Cmv $0000,Color23 ;
Cmv $0000,Color24 ;
Cmv $0000,Color25 ;
Cmv $0000,Color26 ;
Cmv $0000,Color27 ;
Cmv $0000,Color28 ;
Cmv $0000,Color29 ;
Cmv $0000,Color30 ;
Cmv $0000,Color31 ;
Cwt $2f ; Wait for Line $2f
Cmv $0f00,Color00
Cmv $000f,Color01
Cmv -2,BplMod1 ; PlayField 1 Modulo
Cmv -2,BplMod2 ; PlayField 2 Modulo
TextBpls Cmv $000d,BplPt0h ;
Cmv $0000,BplPt0l ;
Cmv $1200,BplCon0
Cwt $30
Cmv $0f03,Color00
Cmv $033f,Color01
Cwt $31
Cmv $0d05,Color00
Cmv $055d,Color01
Cwt $32
Cmv $0b07,Color00
Cmv $077b,Color01
Cwt $33
Cmv $0909,Color00
Cmv $0999,Color01
Cwt $34
Cmv $070b,Color00
Cmv $0bb7,Color01
Cwt $35
Cmv $050d,Color00
Cmv $0dd5,Color01
Cwt $36
Cmv $030f,Color00
Cmv $0ff3,Color01
Cwt $37
Cmv $0200,BplCon0
Cmv (3*$28)-2,BplMod1 ; PlayField 1 Modulo
Cmv (3*$28)-2,BplMod2 ; PlayField 2 Modulo
Bpl0 Cmv $000b,BplPt0h ;
Cmv $0000,BplPt0l ;
Bpl1 Cmv $000b,BplPt1h ; Set PlayField 1 BitPlanes
Cmv $0028,BplPt1l ;
Bpl2 Cmv $000b,BplPt2h ;
Cmv $0050,BplPt2l ;
Bpl3 Cmv $000b,BplPt3h ;
Cmv $0078,BplPt3l ;
Cwt $38 ; Wait for Line $38
Cmv $4200,BplCon0 ; 6 Planes & Dual PlayField
CopperCOLS Cmv $0000,Color00 ;
Cmv $0000,Color01 ;
Cmv $0000,Color02 ;
Cmv $0000,Color03 ; PlayField 1 Colours
Cmv $0000,Color04 ;
Cmv $0000,Color05 ;
Cmv $0000,Color06 ;
Cmv $0000,Color07 ;
Cmv $0000,Color08 ;
Cmv $0000,Color09 ;
Cmv $0000,Color10 ;
Cmv $0000,Color11 ;
Cmv $0000,Color12 ;
Cmv $0000,Color13 ;
Cmv $0000,Color14 ;
Cmv $0000,Color15 ;
Pal ; Wait For Pal
Cwt $28 ; Wait For Line $12f
Cmv $0200,BplCon0 ; Switch off BitPlanes
Cmv $0000,Color00 ; Black into Colour 0
EndCop ; End the CopperList
*****************************************************************************
* External Data *
*****************************************************************************
BlackOut Dc.w 0,0,0,0,0,0,0,0
Dc.w 0,0,0,0,0,0,0,0
PiccyCols0 Dc.w $000,$fff,$aaa,$555,$8af,$55d,$32b,$309
Dc.w $ff0,$fa0,$f50,$f00,$0f5,$0b2,$071,$030
PiccyCols1 Dc.w $000,$fff,0,0,0,0,0,0
Dc.w 0,0,0,0,0,0,0,0
Incdir Df1:ShootEmUp
AlienGFX1 Incbin Aliens16.Raw ; Blitter Graphics
AlienMask1 Incbin Aliens16.Mask ; Blitter Mask
FontGFX Incbin Font.Raw ; Font Graphics
TextPiccy Ds.b 400
BlitBuffer Ds.b (44*4*10) ; For Off screen blitting so
; DO NOT REMOVE!!
Piccy1 Ds.b (44*4*280)
Piccy2 Ds.b (44*4*280)
*****************************************************************************
* Custom Chip Registers *
*****************************************************************************
;Control Registers
Dmaconr = $002
Vposr = $004
Vhposr = $006
Joy0dat = $00A
Joy1dat = $00C
Clxdat = $00E
Intenar = $01C
Intereqr = $01E
Copcon = $02E
;Blitter Registers
Bltcon0 = $040
Bltcon1 = $042
Bltafwm = $044
Bltalwm = $046
Bltcpth = $048
Bltcptl = $04A
Bltbpth = $04C
Bltbptl = $04E
Bltapth = $050
Bltaptl = $052
Bltdpth = $054
Bltdptl = $056
Bltsize = $058
Bltcmod = $060
Bltbmod = $062
Bltamod = $064
Bltdmod = $066
Bltcdat = $070
Bltbdat = $072
Bltadat = $074
;Copper Registers
Cop1lc = $080
Cop1lch = $080
Cop1lcl = $082
Cop2lc = $084
Cop2lch = $084
Cop2lcl = $086
Copjmp1 = $088
Copjmp2 = $08A
Diwstrt = $08E
Diwstop = $090
Ddfstrt = $092
Ddfstop = $094
Dmacon = $096
Clxcon = $098
Intena = $09A
Intreq = $09C
;BitPlane Registers
BplCon0 = $100
BplCon1 = $102
BplCon2 = $104
BplMod1 = $108
BplMod2 = $10a
BplPt0h = $0e0
BplPt0l = $0e2
BplPt1h = $0e4
BplPt1l = $0e6
BplPt2h = $0e8
BplPt2l = $0ea
BplPt3h = $0ec
BplPt3l = $0ee
BplPt4h = $0f0
BplPt4l = $0f2
BplPt5h = $0f4
BplPt5l = $0f6
;Colorour Registers
Color00 = $180
Color01 = $182
Color02 = $184
Color03 = $186
Color04 = $188
Color05 = $18a
Color06 = $18c
Color07 = $18e
Color08 = $190
Color09 = $192
Color10 = $194
Color11 = $196
Color12 = $198
Color13 = $19a
Color14 = $19c
Color15 = $19e
Color16 = $1a0
Color17 = $1a2
Color18 = $1a4
Color19 = $1a6
Color20 = $1a8
Color21 = $1aa
Color22 = $1ac
Color23 = $1ae
Color24 = $1b0
Color25 = $1b2
Color26 = $1b4
Color27 = $1b6
Color28 = $1b8
Color29 = $1ba
Color30 = $1bc
Color31 = $1be